
#include "module_events.h"


//Holds function references for each signal
Slot _slots[SIGNAL_SIZE][MAX_SLOTS];
//Size of malloced array per signal
uint8_t _slots_size[SIGNAL_SIZE];

int8_t signal(Signal sig, void *pt_data, uint16_t size)
{
	Event ev;
	ev.sig = sig;
	ev.time = time();
	ev.data = pt_data;
	ev.size = size;
	
	/* Emit the signal to slots */
	uint8_t i;
	for(i=0;i<_slots_size[sig];i++)
	{
		_slots[sig][i](&ev);
	}
	
	return 1;
}

int8_t register_slot(Slot slot, Signal sig)
{
	#ifdef DEBUG
	char *debug = (char *) malloc(sizeof(char)*50);
	sprintf(debug, "* Adding slot 0x%x to signal %i...", slot, sig);
	usart_write(debug);
	free(debug);
	#endif
	if(_slots_size[sig] == MAX_SLOTS)
	{
		usart_writeln("ERROR: ALL SLOTS ARE USED");
		slots_registered();
		return 0;
	}
	_slots[sig][_slots_size[sig]] = slot;
	_slots_size[sig]++;
	return 1;
}

void unregister_slot(Slot slot, Signal sig)
{
	#ifdef DEBUG
	char *debug = (char *) malloc(sizeof(char)*50);
	sprintf(debug, "* Removing slot 0x%x from signal %i...", slot, sig);
	usart_write(debug);
	free(debug);
	#endif

	uint8_t i, shift_left;
	shift_left = 0;
	for(i=0;i<_slots_size[sig];i++)
	{
		if(_slots[sig][i] == slot)
		{
			_slots[sig][i] = NULL;
			shift_left = 1;
		}
		
		if(shift_left && (i+1) < _slots_size[sig])
			_slots[sig][i] = _slots[sig][i+1];
	}
	if(shift_left)
	{
		_slots[sig][_slots_size[sig]-1] = NULL;
		_slots_size[sig]--;
	}
}

void slots_registered(void)
{
	usart_writeln(txt_separator_line);
	usart_writeln("Slots registered:");
	uint8_t sig,i;
	char *temp = (char *) malloc(sizeof(char)*20);
	for(sig=0;sig<SIGNAL_SIZE;sig++)
	{
		sprintf(temp, "Signal %i: ",sig);
		usart_write(temp);
		for(i=0;i<_slots_size[sig];i++)
		{
			sprintf(temp, "0x%x ",(unsigned int)_slots[sig][i]);
			usart_write(temp);
		}
		usart_writeln("");
	}
	free(temp);
	usart_writeln(txt_separator_line);
}
